package com.snow;

import com.google.protobuf.ByteString;
import com.snow.proto.my_wechat.*;
import dbcTools.DBC_MySQL;
import io.grpc.stub.StreamObserver;

import javax.sql.rowset.serial.SerialBlob;
import java.io.IOException;
import java.sql.*;
import java.util.HashSet;
import java.util.Iterator;

public class MyWeChatImpl extends MyWeChatServiceGrpc.MyWeChatServiceImplBase {
    @Override
    public void getGroupMessage(GroupId request, StreamObserver<GroupMessage> responseObserver) {
//        super.getGroupMessage(request, responseObserver);
        int groupId = request.getGroupId();
        if (MyWechatServer.responseObserverKV.containsKey(groupId)){
            MyWechatServer.responseObserverKV.get(groupId).add(responseObserver);
        } else {
            HashSet<StreamObserver<GroupMessage>> hashSet = new HashSet<>();
            hashSet.add(responseObserver);
            MyWechatServer.responseObserverKV.put(groupId, hashSet);
        }
    }

    @Override
    public void sendGroupMessageByGroupId(GroupMessage request, StreamObserver<SendState> responseObserver) {
//        super.sendGroupMessageByGroupId(request, responseObserver);

        String sql = "INSERT INTO group_message (group_id, creation_time, user_id, content_type, content) VALUES (?, ?, ?, ?, ?)";
        try {
            PreparedStatement preparedStatement = MyWechatServer.connection.prepareStatement(sql);
            preparedStatement.setInt(1, request.getGroupId());
            preparedStatement.setLong(2, request.getCreationTime());
            preparedStatement.setInt(3, request.getUserId());
            preparedStatement.setString(4, request.getContentType());
            preparedStatement.setBlob(5, new SerialBlob(request.getContent().toByteArray()));
            int status = preparedStatement.executeUpdate();
            responseObserver.onNext(SendState.newBuilder().setSendState(status > 0 ? true : false).build());
            responseObserver.onCompleted();

            HashSet<StreamObserver<GroupMessage>> hashSet = MyWechatServer.responseObserverKV.get(request.getGroupId());
            Iterator<StreamObserver<GroupMessage>> iterator = hashSet.iterator();
            while (iterator.hasNext()){
                StreamObserver<GroupMessage> streamObserver = iterator.next();
                streamObserver.onNext(
                        GroupMessage.newBuilder()
                                .setGroupId(request.getGroupId())
                                .setCreationTime(request.getCreationTime())
                                .setUserId(request.getUserId())
                                .setContentType(request.getContentType())
                                .setContent(request.getContent()).build()
                );
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void getGroupMessagesByGroupId(GroupId request, StreamObserver<GroupMessages> responseObserver) {
//        super.getGroupMessagesByGroupId(request, responseObserver);
        int group_id = request.getGroupId();
        String sql = "SELECT * FROM group_message WHERE group_id = ?";

        try {
            PreparedStatement preparedStatement = MyWechatServer.connection.prepareStatement(sql);
            preparedStatement.setInt(1, group_id);
            ResultSet resultSet = preparedStatement.executeQuery();

            GroupMessages.Builder groupMessagesBuilder = GroupMessages.newBuilder();
            GroupMessage groupMessage;
            Blob contentBlob;
            ByteString contentByteString;
            while (resultSet.next()){
                contentBlob = resultSet.getBlob("content");
                contentByteString = ByteString.readFrom(contentBlob.getBinaryStream());

                groupMessage = GroupMessage.newBuilder()
                        .setGroupId(resultSet.getInt("group_id"))
                        .setCreationTime(resultSet.getLong("creation_time"))
                        .setUserId(resultSet.getInt("user_id"))
                        .setContentType(resultSet.getString("content_type"))
                        .setContent(contentByteString).build();
                groupMessagesBuilder.addGroupMessage(groupMessage);
            }
            responseObserver.onNext(groupMessagesBuilder.build());
            responseObserver.onCompleted();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void getUserInfoByAccountPassword(AccountPassword request, StreamObserver<UserInfo> responseObserver) {
//        super.getUserInfoByAccountPassword(request, responseObserver);
        String account = request.getAccount();
        String password = request.getPassword();

        String sql = "SELECT * FROM `user` WHERE account = ? && `password` = ?";
        try {
            PreparedStatement preparedStatement = MyWechatServer.connection.prepareStatement(sql);
            preparedStatement.setString(1, account);
            preparedStatement.setString(2, password);
            ResultSet resultSet = preparedStatement.executeQuery();

            UserInfo userInfo;
            if (resultSet.next()){
                Blob avatarBlob = resultSet.getBlob("avatar");
                ByteString avatarByteString = ByteString.readFrom(avatarBlob.getBinaryStream());

                userInfo = UserInfo.newBuilder()
                        .setId(resultSet.getInt("id"))
                        .setAvatarType(resultSet.getString("avatar_type"))
                        .setAvatar(avatarByteString)
                        .setName(resultSet.getString("name"))
                        .setGender(resultSet.getString("gender"))
                        .setAddress(resultSet.getString("address"))
                        .setSign(resultSet.getString("sign"))
                        .setAccount(resultSet.getString("account"))
                        .setPassword(resultSet.getString("password"))
                        .setWechatNumber(resultSet.getString("wechat_number"))
                        .setWechatNumberSeted(resultSet.getBoolean("wechat_number_seted"))
                        .setCreationTime(resultSet.getTimestamp("creation_time").getTime()).build();
            }else{
                userInfo = UserInfo.newBuilder().setId(-1).build();
            }

            responseObserver.onNext(userInfo);
            responseObserver.onCompleted();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void getFriendInfoListByUserId(UserId request, StreamObserver<FriendInfoList> responseObserver) {

//        super.getFriendListInfoByUserId(request, responseObserver);
        int user_id = request.getUserId();
        String sql = "SELECT group_member.group_id,`user`.id,`user`.avatar_type,`user`.avatar,`user`.`name` " +
                "FROM `user`,group_member, " +
                    "(SELECT group_member.group_id " +
                    "FROM group_member,`group` " +
                    "WHERE group_member.group_id = `group`.id " +
                        "&& group_member.user_id = ? " +
                        "&& `group`.nature = '好友群') as friends_group_id " +
                "WHERE friends_group_id.group_id = group_member.group_id " +
                    "&& group_member.user_id = `user`.id " +
                    "&& group_member.user_id != ? ";

        try {
            PreparedStatement preparedStatement = MyWechatServer.connection.prepareStatement(sql);
            preparedStatement.setInt(1, user_id);
            preparedStatement.setInt(2, user_id);
            ResultSet resultSet = preparedStatement.executeQuery();
            Blob avatarBlob;
            ByteString avatarByteString;
            FriendInfo friendInfo;
            FriendInfoList.Builder friendInfoListBuilder = FriendInfoList.newBuilder();
            while (resultSet.next()){
                avatarBlob = resultSet.getBlob("avatar");
                avatarByteString = ByteString.readFrom(avatarBlob.getBinaryStream());

                friendInfo = FriendInfo.newBuilder()
                        .setGroupId(resultSet.getInt("group_id"))
                        .setId(resultSet.getInt("id"))
                        .setAvatarType(resultSet.getString("avatar_type"))
                        .setAvatar(avatarByteString)
                        .setName(resultSet.getString("name")).build();

                friendInfoListBuilder.addFriendInfo(friendInfo);
            }
            FriendInfoList friendInfoList = friendInfoListBuilder.build();
            responseObserver.onNext(friendInfoList);
            responseObserver.onCompleted();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
